import sqlite3
import pytest
from appium import webdriver
from appium.options.android import UiAutomator2Options
# import pymysql
import subprocess
from datetime import datetime

# 初始化“全局变量”
@pytest.fixture(scope="session")
def global_variable():
    global_var = {'version': '1.0'}
    global_var = {'name': 'mall'}
    return global_var

# # 测试会话开始前被调用
# @pytest.fixture(scope="session")
# def pytest_sessionstart(session):
#     print("-----android测试会话开始------")

# # 测试会话(成功/失败/跳过)结束后被调用
# @pytest.fixture(scope="session")
# def pytest_sessionfinish(session, request,exitstatus):
#     print("-----android测试会话结束------")
#     # 生成测试报告
#     allure generate "D:\allure-results  -o D:\reports\allure-reports   --clean "
#     allure_reports_url=request.config.getoption('--allure_reports_url')
#     allure open -h allure_reports_url -p 8083 "D:\reports\allure-reports"      


# 测试会话开始前被调用
def pytest_sessionstart(session):
    print("-----web测试会话开始------")

# 测试会话(成功/失败/跳过)结束后被调用
def pytest_sessionfinish(session,exitstatus):
    print("-----web测试会话结束------")
    # 生成测试报告,打开网页展示报告
    alluredir=session.config.getoption('--alluredir')
    allure_reports=session.config.getoption('--allure_reports')
    platform_name=session.config.getoption('--platform_name')
    allure_reports_url=session.config.getoption('--allure_reports_url')
    allure_reports_url_port=session.config.getoption('--allure_reports_url_port')

    # 获取当前时间作为目录名
    timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
    # 生成测试报告
    generate_command = f'allure generate "{alluredir}" -o "{allure_reports}/"'+platform_name+'/'+timestamp
    try:
        subprocess.run(generate_command, shell=True, check=True)
    except subprocess.CalledProcessError as e:
        print(f"Failed to generate Allure report: {e}")
    
    # 打开测试报告
    if allure_reports_url:
        open_command = f'allure open -h "{allure_reports_url}" -p "{allure_reports_url_port}" "{allure_reports}"'
        try:
            subprocess.run(open_command, shell=True, check=True)
        except subprocess.CalledProcessError as e:
            print(f"Failed to open Allure report: {e}")

def pytest_addoption(parser):
    parser.addoption("--platform_name", action="store",help="Platform name for Appium.")
    parser.addoption("--automation_name", action="store", help="Automation name for Appium.")
    parser.addoption("--device_name", action="store",help="Device name for Appium.")
    parser.addoption("--app_package_name", action="store", help="Application package name.")
    parser.addoption("--app_activity_name", action="store", help="Application activity name.")
    parser.addoption("--app_url", action="store", help="URL/path to the application APK.")
    parser.addoption("--webdriver_url_appium", action="store",  help="URL/path to the webdriver_url_appium.")
    parser.addoption("--allure_reports_url", action="store",  help="URL/path to the allure_reports_url.")
    parser.addoption("--allure_reports_url_port", action="store",  help="URL/path to the allure_reports_url_port.")
#初始化：测试函数引用driver打开设备时，需要空白设备时引用这个
@pytest.fixture(scope="function")
def appium_driver_none(request):
    desired_caps = {
        'platformName': request.config.getoption('--platform_name'),
        'automationName': request.config.getoption('--automation_name'),
        'deviceName': request.config.getoption('--device_name'),
        'app': request.config.getoption('--appUrl'),
        'autoGrantPermissions': True,
        'allowInsecure': ['adb_shell'] ,
    }
    options = UiAutomator2Options().load_capabilities(desired_caps)
    options.set_capability('allowInsecure', ['adb_shell'])
    driver = webdriver.Remote(request.config.getoption('--webdriver_url_appium'), options=options)
    yield driver  
    driver.quit()   

#初始化： 测试函数引用driver打开设备应用时需要完全干净设备环境时用这个
@pytest.fixture(scope="function")
def appium_driver_fullReset(request):
    desired_caps = {
        'platformName': request.config.getoption('--platform_name'),
        'automationName': request.config.getoption('--automation_name'),
        'deviceName': request.config.getoption('--device_name'),
        'appPackage':  request.config.getoption('--app_package_name'),
        'appActivity': request.config.getoption('--app_activity_name'), 
        'app': request.config.getoption('--appUrl'),
        'autoGrantPermissions': True,
        'allowInsecure': ['adb_shell'] ,
        'fullReset': True,   #重装应用
        # 'fastReset': True, 
        # 'noReset': True,
    }
    options = UiAutomator2Options().load_capabilities(desired_caps)
    options.set_capability('allowInsecure', ['adb_shell'])
    driver = webdriver.Remote(request.config.getoption('--webdriver_url_appium'), options=options)
    yield driver  
    driver.quit()    

#初始化： 测试函数引用driver打开设备应用时不重装应用但需要清空应用所有数据时用这个
@pytest.fixture(scope="module") 
def appium_driver_fastReset(request):
    desired_caps = {
        'platformName': request.config.getoption('--platform_name'),
        'automationName': request.config.getoption('--automation_name'),
        'deviceName': request.config.getoption('--device_name'),
        'appPackage':  request.config.getoption('--app_package_name'),
        'appActivity': request.config.getoption('--app_activity_name'), 
        'app': request.config.getoption('--appUrl'),
        'autoGrantPermissions': True,
        'allowInsecure': ['adb_shell'] ,
        # 'fullReset': True,   #重装应用
        'fastReset': True, 
        # 'noReset': True,
    }
    options = UiAutomator2Options().load_capabilities(desired_caps)
    options.set_capability('allowInsecure', ['adb_shell'])
    driver = webdriver.Remote(request.config.getoption('--webdriver_url_appium'), options=options)
    yield driver  
    driver.quit()


#初始化：切换webview_context
def test_switch_to_webview_context(driver):
    # 切换到Webview上下文,不然除了原生的控件可以获取，其他vue组件无法获取
    print("====切换webview_context=======")
    contexts = driver.contexts
    webview_context = None
    for context in contexts:
        if 'WEBVIEW' in context:
            webview_context = context
            break
    if webview_context:
        driver.switch_to.context(webview_context)
        print(f"Switched11111 to {webview_context}")
    # 切换回Native上下文
    # native_context = [context for context in contexts if 'NATIVE_APP' in context][0]
    # driver.switch_to.context(native_context)

#初始化： 创建mysql数据库连接
# @pytest.fixture(scope="module")
# def db_connection():
#     connection = pymysql.connect(
#         host='your_host',
#         user='your_username',
#         password='your_password',
#         database='your_database',
#         charset='utf8mb4',
#         cursorclass=pymysql.cursors.DictCursor
#     )
#     # 返回连接对象
#     yield connection
#     # 断开连接
#     connection.close()

#初始化：创建sqlite3数据库连接
@pytest.fixture(scope='session')
def db_connection():
    # 连接数据库
    conn = sqlite3.connect(':memory:')  # 这里使用内存数据库作为示例，你可以改为文件路径或其他数据库URL
    yield conn  # 1、yield语句之前的代码会在调用这个fixture函数的测试函数开始前执行，用于设置或初始化资源，2、yield conn cursor表示yield返回值conn和cursor传递给测试函数，3、yield语句后面的所有代码在测试函数执行完毕后执行，主要用于清理资源
    # 在所有测试结束后关闭连接
    conn.close()



# @pytest.fixture(scope="session")
# def get_test_data(where, limitNum):
#     # 创建数据库连接
#     connection = pymysql.connector.connect(
#         host='mysql.sqlpub.com',
#         user='shuwenouwan',
#         password='de1e7fff813c5c4b',
#         database='shuwenouwanmall'
#     )
#     cursor = connection.cursor(dictionary=True)  # 使用字典游标
#     # 执行SQL查询
#     cursor.execute(f"SELECT * FROM test_data WHERE tag='{where}' LIMIT {limitNum}")
#     data = cursor.fetchall()  # 获取所有数据
#     # 关闭连接
#     cursor.close()
#     connection.close()
#     return data 
# def test_invalid_username(get_test_data, driver):
#     for data_item in get_test_data("invalid_register", 3):
#         print("当前测试数据:", data_item)
#         page = LoginPage(driver)
#         page.navigate()
#         page.enter_username(data_item['username']) 
#         page.enter_password(data_item['password']) 
#         page.click_login_button()
#         try:
#             assert not page.is_user_logged_in()
#             assert '无效用户名或密码' in page.get_error_message()
#         except AssertionError as ae:
#             allure.attach(driver.get_screenshot_as_png(), name="测试无效用户名场景：测试不通过!", attachment_type=allure.attachment_type.PNG)
#             raise
